package edu.bu.cs673.superkids123.children.DataObjectAccess;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Restrictions;

import edu.bu.cs673.superkids123.HibernateUtil;
import edu.bu.cs673.superkids123.children.model.CompletedGame;
import edu.bu.cs673.superkids123.children.model.Game;
import edu.bu.cs673.superkids123.children.model.Lesson;
import edu.bu.cs673.superkids123.children.model.Level;
import edu.bu.cs673.superkids123.common.model.Child;

public class LessonGameManager {
	/**
	 * @author Abdelghani Bhalla
	 */

	// add Level
	public static int addLevel(String name, String description, int minAge, int maxAge) {
		int result = -1;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();

			Level level = new Level(name, description, minAge, maxAge);

			result = (Integer) session.save(level);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return result;
	}
	
	/*
	 * Add Level
	 * @param level object
	 */
	public static int addLevel(Level level) {
		int result = -1;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			result = (Integer) session.save(level);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return result;
	}

	// Get Level By Id
	public static Level getLevelById(int id) {
		Level level = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Criteria criteria = session.createCriteria(Level.class);
			criteria.add(Restrictions.eq("id", id)).setMaxResults(1);

			level = (Level) criteria.uniqueResult();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return level;
	}

	// Get All Levels
	@SuppressWarnings("unchecked")
	public static List<Level> getLevels() {
		List<Level> levels = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Query query = session.createQuery("From Level");

			levels = (List<Level>) query.list();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return levels;
	}

	// Get Levels by child age
	@SuppressWarnings("unchecked")
	public static List<Level> getLevelsByAge(int age) {
		List<Level> levels = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Criteria criteria = session.createCriteria(Child.class);
			criteria.add(Restrictions.le("minAge", age)).add(
					Restrictions.ge("maxAge", age));

			levels = (List<Level>) criteria.list();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return levels;
	}

	// Add Lesson
	public static int addLesson(String name, String description, boolean isActive,
			Level level, String image) {
		
		Lesson lesson = new Lesson(name, description, isActive);
		level.addLesson(lesson);
		lesson.setIcon(image);
		
		return addLesson(lesson);
	}
	
	// Add Lesson
	public static int addLesson(String name, String description, boolean isActive,
			Level level) {
		int result = -1;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();

			Lesson lesson = new Lesson(name, description, isActive);
			level.addLesson(lesson);

			result = (Integer) session.save(lesson);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return result;
	}
	
	/*
	 * Add Lesson
	 * @param lesson
	 */
	public static int addLesson(Lesson lesson)
	{
		int result = -1;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			result = (Integer) session.save(lesson);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return result;
	}
	
	// Get Lesson By Id
	public static Lesson getLessonById(int id) {
		Lesson lesson = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Criteria criteria = session.createCriteria(Lesson.class);
			criteria.add(Restrictions.eq("id", id)).setMaxResults(1);

			lesson = (Lesson) criteria.uniqueResult();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return lesson;
	}

	// Get Lesson By Level
	@SuppressWarnings("unchecked")
	public static List<Lesson> getLessonByLevel(Level level) {
		Lesson exampleLesson = new Lesson();
		List<Lesson> lessons = null;
		level.addLesson(exampleLesson);
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Example example = Example.create(exampleLesson);
			Criteria criteria = session.createCriteria(Lesson.class).add(
					example);
			lessons = (List<Lesson>) criteria.list();
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return lessons;
	}

	/*
	 * Get All lesson
	 */
	@SuppressWarnings("unchecked")
	public static List<Lesson> getAllLessons() {
		List<Lesson> lessons = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Query query = session.createQuery("From Lesson");

			lessons = (List<Lesson>) query.list();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return lessons;
	}
	/*
	 * getAllActiveLessons
	 * @param none
	 * Get all lesson that active --> isActive= true
	 */
	@SuppressWarnings("unchecked")
	public static List<Lesson> getAllActiveLessons() {
		List<Lesson> lessons = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Query query = session.createQuery("From Lesson where IsActive=:isActive");
			query.setParameter("isActive", true);
			lessons = (List<Lesson>) query.list();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return lessons;
	}
	
	// Games
	
	// Add Game
	public static int addGame(String name, String description, boolean isActive, Level level) {
		int result = -1;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();

			Game game = new Game(name, description, isActive);
			level.addGame(game);

			result = (Integer) session.save(game);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return result;
	}

	public int addGame(Game game)
	{
		int result = -1;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			result = (Integer) session.save(game);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return result;
	}
	// Get Game By Id
	public static Game getGameById(int id) {
		Game game = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Criteria criteria = session.createCriteria(Game.class);
			criteria.add(Restrictions.eq("id", id)).setMaxResults(1);

			game = (Game) criteria.uniqueResult();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return game;
	}

	// Get Game By Level
	@SuppressWarnings("unchecked")
	public static List<Game> getGameByLevel(Level level) {
		Game exampleGame = new Game();
		List<Game> games = null;
		level.addGame(exampleGame);
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Example example = Example.create(exampleGame);
			Criteria criteria = session.createCriteria(Lesson.class).add(
					example);
			games = (List<Game>) criteria.list();
			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return games;
	}
	
	/*
	 * getAllActiveGames
	 * @param none
	 * Get all games that active --> isActive= true
	 */
	@SuppressWarnings("unchecked")
	public static List<Game> getAllActiveGames() {
		List<Game> games = null;
		Transaction tx = null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {

			tx = session.beginTransaction();
			Query query = session.createQuery("From Game where IsActive=:isActive");
			query.setParameter("isActive", true);
			games = (List<Game>) query.list();

			session.getTransaction().commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return games;
	}
	
	
	public static Lesson[] getLessons()
	{
		 return getAllActiveLessons().toArray(new Lesson[0]);
	}
	public static Game[] getGames()
	{
		 return getAllActiveGames().toArray(new Game[0]);
	}
}
